package zhongbo.javaweb.instagram.util.sha256;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

/**
 * HmacSHA256 算法,返回小写
 * Created by zhongbo on 2017/11/15 0015.
 *
 * @author zhongbo
 * @since 2017/11/15
 */
public class HmacSha256Util {
    /**
     * 签名算法HmacSha256
     */
    private static final String HMAC_SHA256 = "HmacSHA256";
    private static final String USE_CHARSET = "utf-8";
    private static String DEFAULT_SECRET = "wholeWebcLz";

    /**
     * 首先初始化一个字符数组，用来存放每个16进制字符
     */
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static String getHmacSha256(String secret, String input) {
        if (null == input) {
            return null;
        }

        try {
            /* 输入按编码转成字节数组*/
            byte[] inputBytes = input.getBytes(USE_CHARSET);
            /* 密码*/
            byte[] secretBytes = secret.getBytes(USE_CHARSET);
            return getHmacSha256(secretBytes, inputBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getHmacSha256(String input) {
        return getHmacSha256(DEFAULT_SECRET, input);
    }

    public static String getHmacSha256(byte[] inputBytes) {
        if (null == inputBytes) {
            return null;
        }

        try {
            // 密码
            byte[] secretBytes = DEFAULT_SECRET.getBytes(USE_CHARSET);
            return getHmacSha256(secretBytes, inputBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getHmacSha256(byte[] secretBytes, byte[] inputBytes) {
        if (null == inputBytes) {
            return null;
        }

        try {
            // 获取摘要器
            Mac mac = Mac.getInstance(HMAC_SHA256);
            mac.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, HMAC_SHA256));
            // 转换结果，也是字节数组，包含16个元素,传入字节数组
            byte[] resultByteArray = mac.doFinal(inputBytes);
            // 字符数组转换成字符串返回
            return bytes2Hex(resultByteArray);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private static String bytes2Hex(byte[] byteArray) {
        // new一个字符数组，这个就是用来组成结果字符串的（解释一下：一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方））
        char[] resultCharArray = new char[byteArray.length * 2];
        // 遍历字节数组，通过位运算（位运算效率高），转换成字符放到字符数组中去
        int index = 0;
        for (byte b : byteArray) {
            resultCharArray[index++] = HEX_DIGITS[b >>> 4 & 0xf];
            resultCharArray[index++] = HEX_DIGITS[b & 0xf];
        }
        // 字符数组组合成字符串返回
        return new String(resultCharArray);

    }

    public static void setDefaultSecret(String defaultSecret) {
        DEFAULT_SECRET = defaultSecret;
    }

    public static void main(String[] args) {
        String hmacSha256 = getHmacSha256("123456");
        System.out.println(hmacSha256);
    }

}
